home *** CD-ROM | disk | FTP | other *** search
/ No Fragments Archive 12: Textmags & Docs / nf_archive_12.iso / MAGS / SOURCES / ATARI_SRC.ZIP / atari source / HDX_BACK / HDX401.ATB / STEPART.C < prev    next >
Encoding:
C/C++ Source or Header  |  2001-02-09  |  19.1 KB  |  678 lines

  1. /*
  2.  * Partition editing and picking.
  3.  *
  4.  * 09-Dec-87    ml.    Added pheader() to take care of placing partition
  5.  *            headers at good sectors.
  6.  * 14-Jan-88    ml.    Added chkpart() to make sure partition scheme does
  7.  *            not map pass end of device.
  8.  * 02-Dec-88     jye. Change and add codes so that can be used for MS-DOS
  9.  *
  10.  * 12-Dec-89    jye. Fixed a bug in stuffamt() so that correctly show three
  11.  *                digits or more in the partitioning deialog box.
  12.  */
  13.  
  14. #include "obdefs.h"
  15. #include "gemdefs.h"
  16. #include "osbind.h"
  17. #include "mydefs.h"
  18. #include "part.h"
  19. #include "bsl.h"
  20. #include "hdx.h"
  21. #include "addr.h"
  22. #include "myerror.h"
  23.  
  24. #define ROLL1 1            /* move the bar one step */
  25. #define ROLL4 4            /* move the bar four steps */
  26. #define NULL 0L            /* the nill pointer */
  27.  
  28. extern int wdesk;
  29. extern int hdesk;
  30. extern long gbslsiz();
  31. extern long bslsiz;
  32. extern SECTOR badbuf[];        /* bad sectors buffer */
  33. extern long ostack;
  34. extern long sptrk;                /* sector per track */
  35. extern long disksiz;            /* size of disk in blocks */
  36. extern int yesscan;            /* the flag for the func. IBMGPART use */
  37. extern int npart;            /* number of partitions */
  38. extern int ext;            /* the index that point to the extended partition */
  39. extern int extend;        /* the index that point to the end of extended */
  40. extern char ttscsi;        /* 1: SCSI bus drive */
  41.  
  42.  
  43. /*
  44.  * Global variables these routines communicate with
  45.  *
  46.  */
  47. static PART *pinfo;        /* -> partition block */
  48. static int totcyl;        /* total # of cylinder */
  49. static long sizleft;    /* size of unused disk in blocks */
  50. static long extleft;    /* size of unused extended partition in blocks */
  51. static int formw, formh;
  52. static int lx, ly, sx, sy;
  53. static int ok2draw;        /* 0: don't draw PARTPNL boxes */
  54. static char partnames[NAMSIZ];    /* partition name buffer */
  55. static int menuflg;        /* negative: never called partmenu */
  56. static int pnlflg;        /* 1: partition scheme comes from panel */
  57. static int along;        /* 1: will not redraw and clean the box */
  58. static int first;        /* flag for add bad and good sectors only one time */
  59. long sumsiz;            /* the sum of bytes of root sectors */
  60. int tolpart;            /* the total of number partitions */
  61. int epty;                /* the y-coordinate of the moving bar */
  62. int uplim;                /* index of dialog box */
  63. int lowlim;                /* index of dialog box */
  64. int restept;            /* 1: rest the moving bar to initial place */
  65. DPART *headptr;            /* the head pointer of structure */
  66. long ratio, bps;
  67. long nill = (long)NULL;
  68. int prevnpart;            /* former number of partitions */
  69.  
  70.  
  71.  
  72. spheader(pdev, part)
  73.  
  74. int pdev;    /* physical device number */
  75. PART *part;    /* partition info */
  76.  
  77. {
  78.     /* Maximum sizes for FAT, root directory and header <in sectors> */
  79.     long  maxdent;        /* max num entries in root dir */
  80.     long  start;        /* starting sector number of a partition */
  81.     long  entries, nument();
  82.     long  movehdr, temstart, moved, psiz;
  83.     UWORD maxfsiz, maxdsiz, hdrsiz;
  84.     long currbsiz;        /* size of BSL b4 pheader is executed */
  85.     int  pno;            /* partition being dealt with */
  86.     int  done;            /* tell if location of header is found */
  87.     int  curr;            /* current sector of header being checked */
  88.     int  ret;            /* return code from testing header sectors */
  89.     int     spc;            /* sectors per cluster */
  90.     int  kindfat;       /* 12 bits fat or 16 bits fat */
  91.     int  step;            /* the index for check the partitions */
  92.     long bigsect(), nsect;
  93.     long stbigsect();
  94.     long temsect, remain;
  95.     long cell();
  96.     
  97.     
  98.     /* get the BSL ready ofr later */
  99.     entries = nument(MEDIA);
  100.     sortbsl(entries);
  101.     currbsiz = bslsiz;
  102.  
  103.     /* Determine actual sizes and starting sectors for all partitions */
  104.     for (pno = 0; pno < npart; pno++) {
  105.         
  106.         /* Partition 0 starts right after root sect.  The rest starts right
  107.            after its previous partition ???*/
  108.         if (pno == 0)
  109.             start = 1 + currbsiz; 
  110.         else if (pno == 4)
  111.             start = part[ext].p_st;    /* start in extened partition */
  112.         else
  113.             start = part[pno-1].p_st + part[pno-1].p_siz;
  114.         
  115.         /* Check if partition exists.  If it doesn't, move on to next one */
  116.         if ((!(part[pno].p_flg & P_EXISTS)) || (pno == ext)) {
  117.             part[pno].p_st = start;
  118.             continue;
  119.         }
  120.         if (pno > 3)     {
  121.             psiz = part[pno].p_siz - ROOTSECT;
  122.         } else    {
  123.             psiz = part[pno].p_siz;
  124.         }
  125.  
  126.         /* estimate the bps */
  127.         /* MAXSECT = 16MB - 8 */
  128.         bps = cell((psiz-7)*BPS, (long)MAXSECT);
  129.         /* the real pbs */
  130.         bps = BPS * n2power((UWORD)cell(bps, (long)BPS));
  131.         ratio = bps / BPS;
  132.         nsect = psiz / ratio;
  133.  
  134.         /* Detail of calculations in part.c dopart() */
  135.         /* find max FAT size. FAT16: 16 bits fat; FAT12: 12bits fat */
  136.         maxfsiz = ((((nsect / SPC) + 2)*2) / bps) + 1;
  137.         /* find max root dir entries */
  138.         if (nsect < 0x5000L)    maxdent = NUMEN;
  139.         else maxdent = nsect / 80;
  140.         maxdent = (maxdent + (bps/BPDIR -1)) & ~(bps/BPDIR -1);
  141.         /* find max root dir size */
  142.         maxdsiz = (maxdent * BPDIR) / bps + 1;
  143.  
  144.            if (pno > 3)    {  /* they are extended partitions */
  145.         /*-------------------------------------------------------*
  146.          * Biggest possible header for a extended partition <in sectors> 
  147.          *    =  Root sector + Boot Sector + 2 FATs + Root Dir    
  148.          *-------------------------------------------------------*/
  149.          /* convert it back to 512 bps size */
  150.             hdrsiz = 1 + ratio + ((maxfsiz * 2) + maxdsiz) * ratio;
  151.         } else
  152.         /*-------------------------------------------------------*
  153.          * Biggest possible header for a partition <in sectors>  *
  154.          *    =  Boot Sector + 2 FATs + Root Dir         *
  155.          *-------------------------------------------------------*/
  156.          /* convert it back to 512 bps size */
  157.             hdrsiz = (1 + (maxfsiz * 2) + maxdsiz) * ratio;
  158.     
  159.     /*-----------------------------------------------------------------*
  160.      * Look for a chunk of sectors starting at "start" (or after, but  *
  161.      * as close as possible) which is big enough to hold the biggest   *
  162.      * possible header.                           *
  163.      *-----------------------------------------------------------------*/
  164.     done = 0;       /* assume correct location not found yet */
  165.     moved = 0;
  166.     while (!done) {
  167.         /*----------------------------------------------------------*
  168.          * Find out if header contains any bad sectors by checking    *
  169.          * range of sectors to be occupied by the header against    *
  170.          * the BSL.                                                    *
  171.          *----------------------------------------------------------*/
  172.         for (curr = 0; curr < hdrsiz; curr++)    {
  173.             if (srchbsl(start+curr, entries) == YES)
  174.                 break;
  175.         }
  176.         if (curr < hdrsiz)    {    /* bad sector found in header */
  177.             /* move header to start after the bad sector */
  178.             moved += curr + 1;
  179.             start += curr + 1;
  180.         } else {
  181.                if ((ret = testhdr(pdev, start, hdrsiz)) < 0)
  182.                  return ERROR;
  183.             if (ret)    {    /* some bad sectors found in header */
  184.                 entries = nument(MEDIA);
  185.                 sortbsl(entries);
  186.             } else {        /* all sectors belong ot header are good */
  187.                 done = 1;
  188.             }
  189.         }
  190.     }
  191.     
  192.     if (moved) {    /* header has been moved */
  193.         /*-------------------------------------------------------*
  194.          * Expand previous partition (except if the current one  *
  195.          * is partition 0, then there is no previous partition), *
  196.          * and enforce maximum partition size on it.         *
  197.          *-------------------------------------------------------*/
  198.         if (ratio > 1)    {    /* big sector */
  199.             start -= moved;
  200.             moved = stbigsect(moved);
  201.             start += moved;
  202.         }
  203.         if (pno > 0) {
  204.             if (part[pno-1].p_siz + moved > disksiz)
  205.                 part[pno-1].p_siz = disksiz;
  206.             else
  207.                 part[pno-1].p_siz += moved;
  208.         }
  209.             
  210.         /* Shrink size of current partition */
  211.         part[pno].p_siz -= moved;
  212.     } 
  213.  
  214.     /* Where current partition should start */
  215.     part[pno].p_st = start;
  216.  
  217.     /* add the waist sectors of big partition to the next partition */
  218.     /* partition #3 in the pinfo is the last partition */
  219.     /* partition # npart-1 in the pinfo is the last partition in 
  220.         the extended partition */
  221.     if ((pno != 3) && (pno != npart - 1) && 
  222.                     (part[pno].p_siz >= MB16))        { /* big partition */
  223.         temsect = part[pno].p_siz;
  224.         if (pno > 3)    { /* extended big partition */
  225.            part[pno].p_siz = ROOTSECT + bigsect(part[pno].p_siz-ROOTSECT);
  226.         } else {    /* prime big partition */
  227.            part[pno].p_siz = bigsect(part[pno].p_siz);
  228.         }
  229.         remain = temsect - part[pno].p_siz;
  230.         if (remain)    {
  231.             part[pno+1].p_siz += remain;
  232.             part[pno+1].p_st -= remain;
  233.         }
  234.     }
  235.  
  236.   }
  237.     /* last existing partition has to sacrifice some space for the BSL    */
  238.     /* and the root sector of device.                    */
  239.     if ((ext == 3) || ((!(part[2].p_flg & P_EXISTS)) &&
  240.                         (!(part[3].p_flg & P_EXISTS))))    { 
  241.         /* the last partition is inside the extended partitions */
  242.         step = npart;
  243.         /* the total extended partition should not inculde the bad sector */
  244.         /* list and root sector */
  245.         part[ext].p_siz -= (currbsiz + 1);
  246.     } else {    /* the last partition is in the prime partitions */
  247.         step = NPARTS;
  248.     }
  249.     for (pno = step-1; pno >= 0; pno--) {
  250.         if (part[pno].p_flg & P_EXISTS) {
  251.             part[pno].p_siz -= (currbsiz + 1);
  252.             break;
  253.         }
  254.     }
  255.  
  256.     /* have to move partitions (existing or not) which start
  257.        right after the BSL if BSL has been expanded  */
  258.     if (bslsiz > currbsiz) {        /* BSL becomes bigger? */
  259.         for (pno = 0; pno < NPARTS; pno++) {
  260.             if (part[pno].p_st == currbsiz + 1) {
  261.                 part[pno].p_st = bslsiz + 1;
  262.                 if (part[pno].p_siz > 0)
  263.                     part[pno].p_siz -= (bslsiz - currbsiz);
  264.             }
  265.         }
  266.     }
  267.   return OK;    /* everything is fine */
  268. }
  269.  
  270.  
  271. long stbigsect(amt)
  272. long amt;
  273.  
  274. {
  275.     long numsect;
  276.     if (ratio > 1)    {
  277.         numsect = (amt % ratio) ? (amt / ratio + 1) : (amt /ratio);
  278.         return(numsect * ratio);
  279.     } else {
  280.         return(amt);
  281.     }
  282. }
  283.  
  284.  
  285. long bigsect(amt)
  286. long amt;
  287.  
  288. {
  289.     if (ratio > 1)    {
  290.         return((amt / ratio) * ratio);
  291.     } else {
  292.         return(amt);
  293.     }
  294. }
  295.  
  296.  
  297. /*
  298.  *  Make sure that sectors assigned to a partition header are GOOD.
  299.  *    Input:
  300.  *        pdev - physical device number partition belongs to.
  301.  *        start - starting (physical) sector number header starts.
  302.  *        hdrsiz - number of sectors header occupies.
  303.  *    Return:
  304.  *        OK - if all sectors in header are good.
  305.  *        positive number - if entries are added to BSL in testing
  306.  *                    the header.
  307.  *        ERROR - if somewhere the process went wrong.
  308.  *    Comments:
  309.  *        Bad Sectors found are added as USER bad sectors.  
  310.  *    First, because we can't expand the VENDOR list while preserving
  311.  *    the USER list.  Second, this is ok, because even if the USER list
  312.  *    is full, the user should reformat the disk anyway, and if the
  313.  *    sector is REALLY bad, it would be discovered again then.
  314.  */
  315. testhdr(pdev, start, hdrsiz)
  316. int pdev;
  317. SECTOR start;
  318. UWORD hdrsiz;
  319. {
  320.     long size, pattern;
  321.     extern long longrandom();
  322.     extern int tformat;        /* flag */
  323.     UWORD sectcnt, list;
  324.     int ret, nbad, clean=1;
  325.     SECTOR sect;
  326.     char *buf;        /* buffer with test data */
  327.     
  328.     size = (long)hdrsiz << 9;
  329.     if ((buf = (char *)Malloc(size)) <= 0) {
  330.         err(nomemory);
  331.         ret = NOMEM;
  332.         goto wrapup;
  333.     }
  334.         
  335.     /*
  336.      * Try to write to header's sectors.
  337.      */
  338.     pattern = longrandom();
  339.     fillbuf(buf, size, pattern);
  340.     sectcnt = hdrsiz;
  341.     sect = start;
  342.     nbad = 0;
  343.  
  344.     if ((ret = wrsects(pdev, sectcnt, buf, sect)) != 0) {
  345.         if (tsterr(ret) == OK) {
  346.             ret = ERROR;
  347.             goto wrapup;
  348.         }
  349.         clean = 0;
  350.         
  351.         while (sectcnt) {    /* find out which sector is indeed bad */
  352.         if ((ret = wrsects(pdev, 1, 0L, sect)) != 0) {
  353.             if (tsterr(ret) == OK) {
  354.                 ret = ERROR;
  355.                 goto wrapup;
  356.             }
  357.             if (sect < 3) {
  358.                 ret = err(rsrvbad);
  359.                 goto wrapup;
  360.             }
  361.                     
  362.                  badbuf[nbad++] = sect;    /* store bad sector num */
  363.                     
  364.                 /* buffer is filled up, have to add bad sectors
  365.                    found so far to the BSL before continuing.   */
  366.                 if (nbad == WARNBADSECTS) {
  367.                     /* Decide which list to add to */
  368.                     if (tformat == TRUE)
  369.                         list = VENDOR;
  370.                     else list = USER;
  371.                        if ((ret=addbsl(pdev, list, nbad)) < 0) {
  372.                            ret = err(rsrvbad);
  373.                            goto wrapup;
  374.                        }
  375.                        nbad = 0;    /* start counting again */
  376.                 }
  377.             }
  378.             sect++;
  379.             sectcnt--;
  380.         }
  381.         if (nbad) {    /* there are bad sectors found not added to BSL yet */
  382.             /* Decide which list to add to */
  383.             if (tformat == TRUE)
  384.                 list = VENDOR;
  385.             else list = USER;
  386.             if ((ret = addbsl(pdev, list, nbad)) < 0) {
  387.                 ret = ERROR;
  388.                 goto wrapup; 
  389.             }
  390.             nbad = 0;
  391.         }
  392.     }
  393.     
  394.     /* Try to read header's sectors */
  395.     sectcnt = hdrsiz;
  396.     sect = start;
  397.     nbad = 0;
  398.     if ((ret = rdsects(pdev, sectcnt, buf, sect)) != 0) {
  399.         if (tsterr(ret) == OK) {
  400.             ret = ERROR;
  401.             goto wrapup;
  402.         }
  403.         clean = 0;
  404.         
  405.         while (sectcnt) {    /* find out which sector is indeed bad */
  406.         if ((ret = rdsects(pdev, 1, buf, sect)) != 0) {
  407.             if (tsterr(ret) == OK) {
  408.                 ret = ERROR;
  409.                 goto wrapup;
  410.             }
  411.                 if (sect < 3) {
  412.             ret = err(rsrvbad);
  413.             goto wrapup;
  414.         }
  415.                     
  416.                  badbuf[nbad++] = sect;    /* store bad sector num */
  417.                     
  418.                 /* buffer is filled up, have to add bad sectors
  419.                    found so far to the BSL before continuing.   */
  420.                 if (nbad == WARNBADSECTS) {
  421.                     /* Decide which list to add to */
  422.                     if (tformat == TRUE)
  423.                     list = VENDOR;
  424.                     else list = USER;
  425.                        if ((ret = addbsl(pdev, list, nbad)) < 0) {
  426.                            ret = ERROR;
  427.                            goto wrapup;
  428.                        }
  429.                        nbad = 0;    /* start counting again */
  430.                 }
  431.             }
  432.             sect++;
  433.             sectcnt--;
  434.         }
  435.         if (nbad) {    /* there are bad sectors found not added to BSL yet */
  436.             /* Decide which list to add to */
  437.             if (tformat == TRUE)
  438.                 list = VENDOR;
  439.             else list = USER;
  440.             if ((ret = addbsl(pdev, list, nbad)) < 0) {
  441.                 ret = ERROR;
  442.                 goto wrapup; 
  443.             }
  444.             nbad = 0;
  445.         }
  446.     }
  447. wrapup:
  448.     if (buf > 0)  Mfree((long)buf);
  449.     
  450.     if (ret < 0)
  451.         return ret;
  452.         
  453.     if (!clean) {
  454.         /* write new bsl back to disk */
  455.         if (wrbsl(pdev) != OK) {
  456.             return ERROR;
  457.         }
  458.         return 1;
  459.     }
  460.         
  461.     return OK;
  462. }
  463.  
  464. long
  465. cell(top, bottom)
  466. long top;
  467. long bottom;
  468. {
  469.     return ((top % bottom) ? (top / bottom + 1) :
  470.             (top / bottom));
  471. }
  472.  
  473.  
  474. n2power(num)
  475. UWORD num;
  476. {
  477.     UWORD power = 1;
  478.  
  479.     for (;;)    {
  480.         if (num <= power )    {
  481.             return (power);
  482.         }
  483.         power <<= 1;
  484.     } 
  485. }
  486.  
  487.  
  488. DPART
  489. *addr(index)
  490. int index;
  491. {
  492.     DPART *temptr;
  493.     int i;
  494.  
  495.     if (index < 0)    return nill;
  496.     if (!index) return (headptr);
  497.     temptr = headptr->next;
  498.     for (i = 1; i < index; i++)    {
  499.         temptr = temptr->next;
  500.     }
  501.     return (temptr);
  502. }
  503.  
  504. DPART
  505. *last()
  506. {
  507.     DPART *temptr;
  508.     int i;
  509.  
  510.     if (!headptr) return (headptr);
  511.     temptr = headptr;
  512.     while (temptr->next)
  513.         temptr = temptr->next;
  514.     return (temptr);
  515. }
  516.  
  517.  
  518.  
  519. creatmem(num)
  520. int num;        /* number of block to malloc */
  521. {
  522.     DPART *temptr;
  523.     DPART *last();
  524.     int i;
  525.  
  526.     if (headptr == nill)    {
  527.         if ((headptr = (DPART *)mymalloc((int)sizeof(DPART))) <= 0)    {;
  528.             err(nomemory);
  529.             if (headptr > 0) free(headptr);
  530.             return ERROR;
  531.         }
  532.         headptr->next = nill;
  533.         headptr->siz = 0L;
  534.         headptr->flg = 0;
  535.     }
  536.     temptr = last();
  537.     for (i = 0; i < num; i++)    {
  538.         if ((temptr->next = (DPART *)mymalloc((int)sizeof(DPART))) <= 0)    {
  539.             err(nomemory);
  540.             if (headptr > 0) free(headptr);
  541.             return ERROR;
  542.  
  543.         }
  544.         temptr = temptr->next;
  545.         temptr->next = nill;
  546.         temptr->siz = 0L;
  547.         temptr->flg = 0;
  548.     }
  549. }
  550.  
  551.  
  552. dpart2part(extpart)
  553. int extpart ;    /* set the extended pointer in the 4th place */
  554. {
  555.     int i;
  556.     DPART *temptr;
  557.  
  558.     /* if npart > 4; need 1 more space for the extended partition */
  559.     if (npart > 4)    {
  560.         i = npart - extend;    /* the index that extended form the end of part. */
  561.         npart += NPARTS-extpart;    /* add 1 extra space for the extended */
  562.                                     /* partition and 0 or 1 or 2 space for */
  563.                                     /* the prime partition in the root */
  564.         extend = npart - i;    /* move 2 space for 2 prime partition in the root */
  565.     } else {                /* set the extpart to -1 */
  566.         npart = 4;
  567.         extpart = -1;
  568.         ext = NO_EXT;
  569.     }
  570.     if ((pinfo = (PART *)Malloc((long)sizeof(PART)*npart)) <= 0)    {
  571.         err(nomemory);
  572.         if (pinfo > 0) Mfree(pinfo);
  573.         free(headptr);
  574.         return ERROR;
  575.     }
  576.     inipart(pinfo, npart);  
  577.     temptr = headptr;
  578.     for (i = 0; i < npart; i++)        {
  579.         if (!(temptr->flg & P_EXISTS)) {
  580.             if (sizleft > 0) {
  581.                 if (temptr->siz > sizleft) {
  582.                     pinfo[i].p_siz = sizleft;
  583.                 }
  584.                 sizleft -= temptr->siz;
  585.             }
  586.         } else {
  587.             pinfo[i].p_siz = temptr->siz;
  588.             pinfo[i].p_flg = P_EXISTS;
  589.             if (i == extpart)    {
  590.                 pinfo[i].p_id[0] = 'X';
  591.                 pinfo[i].p_id[1] = 'G';
  592.                 pinfo[i].p_id[2] = 'M';
  593.                 pinfo[i].p_siz = 0L;
  594.             } else if ((extpart == 1) && ((i == 2) || (i==3)))    {
  595.                 pinfo[i].p_flg = 0;
  596.                 pinfo[i].p_siz = 0L;
  597.             } else if ((extpart == 2) && (i==3))    {
  598.                 pinfo[i].p_flg = 0;
  599.                 pinfo[i].p_siz = 0L;
  600.             } else if (temptr->siz < MB16)    {
  601.                 pinfo[i].p_id[0] = 'G';
  602.                 pinfo[i].p_id[1] = 'E';
  603.                 pinfo[i].p_id[2] = 'M';
  604.                 temptr = temptr->next;
  605.             } else {
  606.                 pinfo[i].p_id[0] = 'B';
  607.                 pinfo[i].p_id[1] = 'G';
  608.                 pinfo[i].p_id[2] = 'M';
  609.                 temptr = temptr->next;
  610.             }
  611.         }
  612.     }
  613.     free(headptr);
  614.     if (extpart != NO_EXT)    {
  615.         asmpart(extpart);
  616.     }
  617.     return OK;
  618. }
  619.  
  620.  
  621. asmpart(extpart)
  622. int extpart ;    /* the extended partition pointer */
  623. {
  624.     int i;
  625.  
  626.     /* # of extened partition to add up */
  627.     for (i = 4; i < extend; i++)        {
  628.         pinfo[extpart].p_siz += pinfo[i].p_siz;
  629.     }
  630.     if (extpart == 3)    {
  631.         return OK;        /* done */
  632.     } else     {
  633.         /* put the last (npart-extend-1) partitions to */
  634.         /* the 3rd or 4th place as prime partitions */
  635.         i = extend;
  636.         if (i < npart)    {
  637.             pinfo[extpart+1].p_siz = pinfo[i].p_siz;
  638.             pinfo[extpart+1].p_flg = P_EXISTS;
  639.             if (pinfo[extpart+1].p_siz < MB16)    {
  640.                 pinfo[extpart+1].p_id[0] = 'G';
  641.                 pinfo[extpart+1].p_id[1] = 'E';
  642.                 pinfo[extpart+1].p_id[2] = 'M';
  643.             } else {
  644.                 pinfo[extpart+1].p_id[0] = 'B';
  645.                 pinfo[extpart+1].p_id[1] = 'G';
  646.                 pinfo[extpart+1].p_id[2] = 'M';
  647.             }
  648.             pinfo[i].p_flg = 0;
  649.             pinfo[i].p_siz = 0L;
  650.             pinfo[i].p_id[0] = '0';
  651.             pinfo[i].p_id[1] = '0';
  652.             pinfo[i].p_id[2] = '0';
  653.             npart--;
  654.         } 
  655.         if (i++ < npart)    {
  656.             pinfo[extpart+2].p_siz = pinfo[i].p_siz;
  657.             pinfo[extpart+2].p_flg = P_EXISTS;
  658.             if (pinfo[extpart+2].p_siz < MB16)    {
  659.                 pinfo[extpart+2].p_id[0] = 'G';
  660.                 pinfo[extpart+2].p_id[1] = 'E';
  661.                 pinfo[extpart+2].p_id[2] = 'M';
  662.             } else {
  663.                 pinfo[extpart+2].p_id[0] = 'B';
  664.                 pinfo[extpart+2].p_id[1] = 'G';
  665.                 pinfo[extpart+2].p_id[2] = 'M';
  666.             }
  667.             pinfo[i].p_flg = 0;
  668.             pinfo[i].p_siz = 0L;
  669.             pinfo[i].p_id[0] = '0';
  670.             pinfo[i].p_id[1] = '0';
  671.             pinfo[i].p_id[2] = '0';
  672.             npart--;
  673.         }
  674.     }
  675. }
  676.  
  677.  
  678.